HDU 5733 tetrahedron(三维几何?公式题。。)
题意:
$给定4个点,判断能否构成四面体,能输出内心坐标和内切球半径$
分析:
$混合积判断四面体存在,delta = A det B dot C$
$delta不为0四面体就存在,然后内切球半径R=\frac{V}{\sum S_{面}}$
$然后内心坐标:$
代码:
//
// Created by TaoSama on 2016-07-19
// Copyright (c) 2016 TaoSama. All rights reserved.
//
#pragma comment(linker, "/STACK:102400000,102400000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
using namespace std;
#define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;
const double EPS = 1e-8, PI = acos(-1);
int sgn(double x) {
return x < -EPS ? -1 : x > EPS;
}
struct Point3 {
double x, y, z;
bool read() {
if(scanf("%lf%lf%lf", &x, &y, &z) == 3) return true;
return false;
}
Point3 operator+(const Point3& p) {
return {x + p.x, y + p.y, z + p.z};
}
Point3 operator-(const Point3& p) {
return {x - p.x, y - p.y, z - p.z};
}
double operator*(const Point3& p) {
return x * p.x + y * p.y + z * p.z;
}
Point3 operator^(const Point3& p) {
return {y* p.z - z * p.y, z* p.x - x * p.z, x* p.y - y * p.x};
}
double length() {
return sqrt(*this * *this);
}
void norm() {
double l = length();
x /= l; y /= l; z /= l;
}
void print() {
printf("%.4f %.4f %.4f", x, y, z);
}
} ps[4];
using Vector3 = Point3;
bool isParallel(Vector3 A, Vector3 B) {
return sgn((A ^ B).length()) <= 0;
}
double point3ToLine(Point3 P, Point3 A, Vector3 v) {
Vector3 w = P - A;
return (v ^ w).length() / v.length();
}
double point3ToPlane(Point3 p, Point3 A, Point3 B, Point3 C) {
Vector3 v = B - A, w = C - A;
Vector3 o = v ^ w;
double pToO = point3ToLine(p, A, o);
double pToA = (p - A).length();
return sqrt(pToA * pToA - pToO * pToO);
}
bool read() {
for(int i = 0; i < 4; ++i)
if(!ps[i].read()) return false;
return true;
}
bool judge() {
Vector3 A = ps[1] - ps[0], B = ps[2] - ps[0], C = ps[3] - ps[0];
Vector3 o = A ^ B;
if(isParallel(A, B)) return false;
if(sgn(o * C) == 0) return false;
return true;
}
double getS(Point3 A, Point3 B, Point3 C) {
double ab = (A - B).length();
double bc = (B - C).length();
double ac = (A - C).length();
double p = (ab + bc + ac) / 2;
double S = sqrt(p * (p - ab) * (p - bc) * (p - ac));
return S;
}
void solve() {
double S1 = getS(ps[0], ps[1], ps[2]); //3
double S2 = getS(ps[0], ps[1], ps[3]); //2
double S3 = getS(ps[0], ps[2], ps[3]); //1
double S4 = getS(ps[3], ps[1], ps[2]); //0
double h = calc(ps[3], ps[0], ps[1], ps[2]);
double V = S1 * h;
double sum = S1 + S2 + S3 + S4;
double R = V / (sum);
double x = (ps[0].x * S4 + ps[1].x * S3 + ps[2].x * S2 + ps[3].x * S1);
x /= sum;
double y = (ps[0].y * S4 + ps[1].y * S3 + ps[2].y * S2 + ps[3].y * S1);
y /= sum;
double z = (ps[0].z * S4 + ps[1].z * S3 + ps[2].z * S2 + ps[3].z * S1);
z /= sum;
printf("%.4f %.4f %.4f %.4f\n", x, y, z, R);
}
int main() {
#ifdef LOCAL
freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);
// freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);
clock_t _ = clock();
while(read()) {
if(!judge()) {
puts("O O O O");
continue;
}
solve();
}
#ifdef LOCAL
printf("\nTime cost: %.2fs\n", 1.0 * (clock() - _) / CLOCKS_PER_SEC);
#endif
return 0;
}